#include "locomanager.h"
#include "nodemanager/wnodemanager.h"
#include "../cmainframe.h"
#include "../cjson.h"

initialiseSingleton(LocoManager);

LocoManager::LocoManager()
{

}

LocoManager::~LocoManager()
{
    deleteAllLocos();
}

bool LocoManager::addLocos(wxVector<wxString> locoName,wxString sectName,int state,int dir)
{
    if(locoName.empty() || sectName == "")
        return false;

    bool isOk = true;
    for(int i=0;i<locoName.size();i++)
    {
        Loco *decLoco = getLocoByName(locoName[i]);
        if(decLoco != NULL)
            return false;
    }

    for(int i=0;i<locoName.size();i++)
    {
        isOk = this->addLoco(locoName[i],sectName,state,false);
    }

    if(locoName.size() >= 2)
    {
        for(int i=0;i<locoName.size()-1;i++)
        {
            Loco *pLoco = this->getLocoByName(locoName[i]);
            Loco *pNextLoco = this->getLocoByName(locoName[i+1]);

            if(pLoco != NULL && pNextLoco != NULL)
            {
                pLoco->setRightLoco(pNextLoco);
                pNextLoco->setLeftLoco(pLoco);
            }
        }

        Loco *pLoco = this->getLocoByName(locoName[locoName.size()-1]);
        Loco *pLastLoco = this->getLocoByName(locoName[locoName.size()-2]);
        if(pLoco != NULL && pLastLoco != NULL)
        {
            pLoco->setLeftLoco(pLastLoco);
        }
    }

    Track *ptrack = this->getTrackByName(sectName);
    if(ptrack != NULL)
    {
        // 如果是加入到前面需要反转
        if(dir == 0)
        {
            std::reverse(locoName.begin(), locoName.end());
        }

        wxString logstr = wxT("添加机车:");
        for(int i=0;i<locoName.size();i++)
        {
            Loco *pLoco = this->getLocoByName(locoName[i]);
            if(pLoco != NULL)
                ptrack->addLoco(pLoco,(SwitchState)state,dir);

            logstr += wxString::Format("%s,",locoName[i]);
        }
        logstr += wxString::Format(wxT("到区段:%s %s."),sectName,(dir == 0 ? wxT("左侧") : wxT("右侧")));

        CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,logstr.ToUTF8().data());

        ptrack->setSectNode(WNodeManager::getSingleton().getSect(sectName));
    }

    return isOk;
}

/// 得到指定名称的轨道
Track* LocoManager::getTrackByName(wxString sectName)
{
    if(sectName == "" || mTracks.empty())
        return NULL;

    //std::lock_guard<std::mutex> lock(mTrackMutex);
    std::map<wxString,Track>::iterator itertrack = mTracks.find(sectName);
    if(itertrack != mTracks.end())
        return &(*itertrack).second;

    return NULL;
}

/// 添加一个机车到系统中
bool LocoManager::addLoco(wxString locoName,wxString sectName,int state,bool isGetPosition,int dir)
{
    if(/*locoName == "" || */sectName == "")
        return false;

    if(locoName != "")
    {
        Loco *decLoco = getLocoByName(locoName);

        if(decLoco != NULL)
            return true;
    }

    Loco *decLoco = new Loco(locoName);

    //std::lock_guard<std::mutex> lock(m_LocoMutex);
    mLocos.push_back(decLoco);

    if(isGetPosition)
    {
        bool isOk = false;
        Track *ptrack = this->getTrackByName(sectName);
        if(ptrack != NULL)
        {
            isOk = ptrack->addLoco(decLoco,(SwitchState)state,dir);
            ptrack->setSectNode(WNodeManager::getSingleton().getSect(sectName));

            CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,
                                                wxString::Format(wxT("添加机车:%s 到区段:%s %s."),
                                                                 locoName,
                                                                 sectName,
                                                                 (dir == 0 ? wxT("左侧") : wxT("右侧"))).ToUTF8().data());
        }
    }

    return true;
}

/// 分离机车
bool LocoManager::uncouplingLoco(int leftLocoId,int rightLocoId)
{
    if((leftLocoId < 0 || leftLocoId >= mLocos.size()) ||
        (rightLocoId < 0 || rightLocoId >= mLocos.size()))
        return false;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);
    Loco *leftLoco = mLocos[leftLocoId];
    Loco *rightLoco = mLocos[rightLocoId];
    if((leftLoco == NULL || rightLoco == NULL) ||
        (leftLoco->getSectNode() != rightLoco->getSectNode()))
        return false;

    Track *decTrack = this->getTrackByName(leftLoco->getSectNode()->sectname);
    if(decTrack == NULL)
        return false;

    if(decTrack->uncouplingLoco(leftLoco,rightLoco))
    {
        decTrack->setSectNode(decTrack->getSectNode());
        CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,wxString::Format(wxT("分离机车:%s,%s"),
                                                                             leftLoco->getName(),
                                                                             rightLoco->getName()).ToUTF8().data());
        return true;
    }

    return false;
}

/// 连接机车
bool LocoManager::couplingLoco(int leftLocoId,int rightLocoId)
{
    if((leftLocoId < 0 || leftLocoId >= mLocos.size()) ||
       (rightLocoId < 0 || rightLocoId >= mLocos.size()))
        return false;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);
    Loco *leftLoco = mLocos[leftLocoId];
    Loco *rightLoco = mLocos[rightLocoId];
    if((leftLoco == NULL || rightLoco == NULL) ||
       (leftLoco->getSectNode() != rightLoco->getSectNode()))
        return false;

    Track *decTrack = this->getTrackByName(leftLoco->getSectNode()->sectname);
    if(decTrack == NULL)
        return false;

    if(decTrack->couplingLoco(leftLoco,rightLoco))
    {
        decTrack->setSectNode(decTrack->getSectNode());
        CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,wxString::Format(wxT("挂接机车:%s,%s"),
                                                                             leftLoco->getName(),
                                                                             rightLoco->getName()).ToUTF8().data());
        return true;
    }

    return false;
}

/// 更改机车
bool LocoManager::changeLoco(int srcLocoId,wxVector<wxString> decLocoName)
{
    if((srcLocoId < 0 || srcLocoId >= mLocos.size()) ||
        (decLocoName.empty()))
        return false;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    // 先清除以前的机车
    Loco* srcLoco = mLocos[srcLocoId];
    if(srcLoco == NULL || srcLoco->getSectNode() == NULL)
        return false;

    wxString newLocoString;

    // 加入机车
    std::vector<Loco*> addLocoArray;
    for(int i=0;i<decLocoName.size();i++)
    {
        Loco *decLoco = getLocoByName(decLocoName[i]);
        if(decLoco == NULL)
        {
            decLoco = new Loco(decLocoName[i]);

            addLocoArray.push_back(decLoco);
            mLocos.push_back(decLoco);

            newLocoString += wxString::Format(wxT("%s-"),decLocoName[i]);
        }
    }

    if(decLocoName.size() >= 2)
    {
        // 为所有的机车建立关系
        for(int i=0;i<decLocoName.size()-1;i++)
        {
            Loco *Loco1 = getLocoByName(decLocoName[i]);
            Loco *Loco2 = getLocoByName(decLocoName[i+1]);
            if(Loco1 != NULL && Loco2 != NULL)
            {
                Loco1->setRightLoco(Loco2);
                Loco2->setLeftLoco(Loco1);
            }
        }

        Loco *Loco1 = getLocoByName(decLocoName[decLocoName.size()-1]);
        Loco *Loco2 = getLocoByName(decLocoName[decLocoName.size()-2]);
        if(Loco1 != NULL && Loco2 != NULL)
            Loco1->setLeftLoco(Loco2);
    }

    Track *decTrack = this->getTrackByName(srcLoco->getSectNode()->sectname);
    if(decTrack == NULL)
        return false;

    // 先加入新的机车
    decTrack->addLocos(addLocoArray,srcLoco);

    // 得到要移动的所有机车
    std::vector<Loco*> decLocoArray;
    Loco *lastLoco = srcLoco->getLeftLoco();
    while(lastLoco != NULL)
    {
        decLocoArray.push_back(lastLoco);
        lastLoco = lastLoco->getLeftLoco();
    }

    decLocoArray.push_back(srcLoco);

    Loco *nextLoco = srcLoco->getRightLoco();
    while(nextLoco != NULL)
    {
        decLocoArray.push_back(nextLoco);
        nextLoco = nextLoco->getRightLoco();
    }

    wxString oldLocoString=wxT("改变机车:");
    for(int i=0;i<decLocoArray.size();i++)
    {
        // 从股道中清除机车
        decTrack->delLoco(decLocoArray[i]);

        // 从系统中删除机车
        std::vector<Loco*>::iterator iterloco = std::find(mLocos.begin(),mLocos.end(),decLocoArray[i]);
        if(iterloco != mLocos.end())
        {
            delete (*iterloco);
            (*iterloco) = NULL;

            mLocos.erase(iterloco);
        }

        oldLocoString += (decLocoArray[i]->getName() + wxT("-"));
    }
    oldLocoString += (wxT("为") + newLocoString);

    decTrack->setSectNode(decTrack->getSectNode());

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,oldLocoString.utf8_string());

    return true;
}

/// 删除机车
void LocoManager::deleteLoco(Loco *ploco)
{
    if(mLocos.empty() || ploco == NULL)
        return;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);
    std::vector<Loco*>::iterator iter = std::find(mLocos.begin(),mLocos.end(),ploco);
    if(iter != mLocos.end())
    {
        delete (*iter);
        (*iter) = NULL;

        mLocos.erase(iter);
    }
}

/// 移动机车2
bool LocoManager::moveLoco2(wxString sectName,int dir)
{
    if(sectName == "")
        return false;

    tagSectNode *srcSectNode = WNodeManager::getSingleton().getSect(sectName);
    if(srcSectNode == NULL)
        return false;

    Track *srcTrack = this->getTrackByName(srcSectNode->sectname);
    if(srcTrack == NULL)
        return false;

    // 先从轨道中清除机车
    std::vector<Loco*> decLocos = srcTrack->delLocoByTrack(srcSectNode->curSwitchState,dir);
    if(decLocos.empty())
        return false;

    srcTrack->setSectNode(srcTrack->getSectNode());

    tagSectNode *decSectNode = WNodeManager::getSingleton().getSect(dir == 0 ? srcSectNode->getLastSect(srcSectNode->curSwitchState) :
                                                                        srcSectNode->getNextSect(srcSectNode->curSwitchState));
    if(decSectNode == NULL)
    {
        for(int i=0;i<decLocos.size();i++) this->deleteLoco(decLocos[i]);
        return false;
    }

    Track *decTrack = this->getTrackByName(decSectNode->sectname);
    if(decTrack == NULL)
    {
        for(int i=0;i<decLocos.size();i++) this->deleteLoco(decLocos[i]);
        return false;
    }

    int decDir = (dir == 0 ? 1 : 0);

    // 如果是加入到前面需要反转
    if(decDir == 0)
        std::reverse(decLocos.begin(), decLocos.end());

    wxString logstr = wxT("移动机车:");
    for(int i=0;i<decLocos.size();i++)
    {
        decTrack->addLoco(decLocos[i],decSectNode->curSwitchState,decDir);

        logstr += wxString::Format(wxT("%s,"),decLocos[i]->getName());
    }
    logstr += wxString::Format(wxT("从区段 %s 到区段 %s."),srcSectNode->sectname,decSectNode->sectname);

    decTrack->setSectNode(decTrack->getSectNode());

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,logstr.utf8_string());

    return true;
}

/// 移动机车
bool LocoManager::moveLoco(int srcLocoId,wxString decLocoName)
{
    if((srcLocoId < 0 || srcLocoId >= mLocos.size()) ||
        (decLocoName == ""))
        return false;

    int decLocoId = -1;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);
    Loco* srcLoco = mLocos[srcLocoId];
    Loco* decLoco = NULL;

    if(decLocoName.ToInt(&decLocoId) &&
        (decLocoId >= 0 && decLocoId < mLocos.size()))
        decLoco = mLocos[decLocoId];

    if((srcLoco == NULL || decLoco == NULL) ||
        (srcLoco == decLoco) ||
        (srcLoco->getSectNode() == NULL || decLoco->getSectNode() == NULL) ||
        srcLoco->getSectNode() == decLoco->getSectNode())
    {
        if(srcLoco != NULL && decLoco == NULL)
        {
            wxString decSectName;
            SwitchState decSwitchState = SwitchState::POSITIVE;

            // 解析 JSON
            cJSON *root = cJSON_Parse(decLocoName.ToStdString().c_str());
            if (root != NULL)
            {
                // 获取 sect 字段
                cJSON *sect = cJSON_GetObjectItemCaseSensitive(root, "sect");
                if (cJSON_IsString(sect) && (sect->valuestring != NULL))
                {
                    decSectName = sect->valuestring;
                }

                // 获取 state 字段
                cJSON *state = cJSON_GetObjectItemCaseSensitive(root, "state");
                if (cJSON_IsNumber(state))
                {
                    decSwitchState = (SwitchState)state->valueint;
                }

                // 释放内存
                cJSON_Delete(root);
            }

            Track *decTrack = this->getTrackByName(decSectName);
            if(decTrack != NULL)
            {
                // 得到要移动的所有机车
                std::vector<Loco*> decLocoArray;
                Loco *lastLoco = srcLoco->getLeftLoco();
                while(lastLoco != NULL)
                {
                    decLocoArray.push_back(lastLoco);
                    lastLoco = lastLoco->getLeftLoco();
                }

                //std::reverse(decLocoArray.begin(), decLocoArray.end());

                decLocoArray.push_back(srcLoco);

                Loco *nextLoco = srcLoco->getRightLoco();
                while(nextLoco != NULL)
                {
                    decLocoArray.push_back(nextLoco);
                    nextLoco = nextLoco->getRightLoco();
                }

                // 从原股道删除这些机车
                Track *srcTrack = this->getTrackByName(srcLoco->getSectNode()->sectname);
                if(srcTrack != NULL)
                {
                    for(int i=0;i<decLocoArray.size();i++)
                    {
                        srcTrack->delLoco(decLocoArray[i]);
                    }

                    srcTrack->setSectNode(srcTrack->getSectNode());
                }

                std::reverse(decLocoArray.begin(), decLocoArray.end());

                wxString decLog = wxT("移动机车:");
                // 在新股道加入这些机车
                for(int i=0;i<decLocoArray.size();i++)
                {
                    decTrack->addLoco(decLocoArray[i],decSwitchState,0);
                    decLog += wxString::Format("%s-",decLocoArray[i]->getName());
                }
                decLog += wxString::Format(wxT(" 到轨道 %s 上."),decTrack->getSectNode()->sectname);

                decTrack->setSectNode(decTrack->getSectNode());

                CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,decLog.ToUTF8().data());

                return true;
            }
        }

        return false;
    }

    // 得到要移动的所有机车
    std::vector<Loco*> decLocoArray;
    Loco *lastLoco = srcLoco->getLeftLoco();
    while(lastLoco != NULL)
    {
        decLocoArray.push_back(lastLoco);
        lastLoco = lastLoco->getLeftLoco();
    }

    //std::reverse(decLocoArray.begin(), decLocoArray.end());

    decLocoArray.push_back(srcLoco);

    Loco *nextLoco = srcLoco->getRightLoco();
    while(nextLoco != NULL)
    {
        decLocoArray.push_back(nextLoco);
        nextLoco = nextLoco->getRightLoco();
    }

    // 从原股道删除这些机车
    Track *srcTrack = this->getTrackByName(srcLoco->getSectNode()->sectname);
    if(srcTrack != NULL)
    {
        for(int i=0;i<decLocoArray.size();i++)
        {
            srcTrack->delLoco(decLocoArray[i]);
        }
        srcTrack->setSectNode(srcTrack->getSectNode());
    }

    // 在新股道加入这些机车
    Track *decTrack = this->getTrackByName(decLoco->getSectNode()->sectname);
    if(decTrack != NULL)
    {
        decTrack->addLocos(decLocoArray,decLoco);
        decTrack->setSectNode(decTrack->getSectNode());
    }

    return true;
}

/// 通过轨道方向删除机车
void LocoManager::deleteLocoByTrack(wxString sectName,int state,int dir)
{
    //std::lock_guard<std::mutex> lock(mTrackMutex);
    std::map<wxString,Track>::iterator itertrack = mTracks.find(sectName);
    if(itertrack == mTracks.end())
        return;

    std::vector<Loco*> decLocoArray = (*itertrack).second.delLocoByTrack(state,dir);
    if(decLocoArray.empty())
        return;

    wxString decString = wxT("删除机车:");
    for(int i=0;i<decLocoArray.size();i++)
    {
        // 从机车管理器中清除机车
        std::vector<Loco*>::iterator iterloco = std::find(mLocos.begin(),mLocos.end(),decLocoArray[i]);
        if(iterloco != mLocos.end())
            mLocos.erase(iterloco);

        decString += wxString::Format("%s,",decLocoArray[i]->getName());

        // 最后删除机车
        delete decLocoArray[i];
        decLocoArray[i] = NULL;
    }

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,decString.ToUTF8().data());
}

/// 通过ID删除机车
void LocoManager::deleteLocoById(int locoId)
{
    if(locoId < 0 || locoId >= mLocos.size())
        return;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    wxString decSectName;
    std::vector<Loco*> decLocoArray;

    if(mLocos[locoId]->getSectNode() != NULL)
        decSectName = mLocos[locoId]->getSectNode()->sectname;

    Loco *lastLoco = mLocos[locoId]->getLeftLoco();
    while(lastLoco != NULL)
    {
        decLocoArray.push_back(lastLoco);
        lastLoco = lastLoco->getLeftLoco();
    }

    std::reverse(decLocoArray.begin(), decLocoArray.end());

    decLocoArray.push_back(mLocos[locoId]);

    Loco *nextLoco = mLocos[locoId]->getRightLoco();
    while(nextLoco != NULL)
    {
        decLocoArray.push_back(nextLoco);
        nextLoco = nextLoco->getRightLoco();
    }

    wxString decString = wxT("删除机车:");
    for(int i=0;i<decLocoArray.size();i++)
    {
        if(decLocoArray[i]->getSectNode() != NULL)
        {
            //std::lock_guard<std::mutex> lock(mTrackMutex);
            // 从轨道中清除这些机车
            std::map<wxString,Track>::iterator itertrack = mTracks.find(decLocoArray[i]->getSectNode()->sectname);
            if(itertrack != mTracks.end())
                (*itertrack).second.delLoco(decLocoArray[i]);
        }

        // 从机车管理器中清除机车
        std::vector<Loco*>::iterator iterloco = std::find(mLocos.begin(),mLocos.end(),decLocoArray[i]);
        if(iterloco != mLocos.end())
            mLocos.erase(iterloco);

        decString += wxString::Format("%s,",decLocoArray[i]->getName());

        // 最后删除机车
        delete decLocoArray[i];
        decLocoArray[i] = NULL;
    }

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,decString.ToUTF8().data());

    Track *pTrack = this->getTrackByName(decSectName);
    if(pTrack != NULL)
    {
        pTrack->setSectNode(pTrack->getSectNode());
    }
}

/// 删除一个机车
void LocoManager::deleteLocoByName(wxString locoName)
{
    if(locoName == "" || this->getLocoByName(locoName) == NULL)
        return;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    wxString decSectName;
    std::vector<Loco*> decLocoArray;
    std::vector<Loco*>::iterator iter = mLocos.begin();
    for(;iter != mLocos.end();++iter)
    {
        if((*iter)->getName() != locoName)
            continue;

        if((*iter)->getSectNode() != NULL)
            decSectName = (*iter)->getSectNode()->sectname;

        Loco *lastLoco = (*iter)->getLeftLoco();
        while(lastLoco != NULL)
        {
            decLocoArray.push_back(lastLoco);
            lastLoco = lastLoco->getLeftLoco();
        }

        std::reverse(decLocoArray.begin(), decLocoArray.end());

        decLocoArray.push_back((*iter));

        Loco *nextLoco = (*iter)->getRightLoco();
        while(nextLoco != NULL)
        {
            decLocoArray.push_back(nextLoco);
            nextLoco = nextLoco->getRightLoco();
        }

        break;
    }

    wxString decString = wxT("删除机车:");
    for(int i=0;i<decLocoArray.size();i++)
    {
        if(decLocoArray[i]->getSectNode() != NULL)
        {
            //std::lock_guard<std::mutex> lock(mTrackMutex);
            // 从轨道中清除这些机车
            std::map<wxString,Track>::iterator itertrack = mTracks.find(decLocoArray[i]->getSectNode()->sectname);
            if(itertrack != mTracks.end())
                (*itertrack).second.delLoco(decLocoArray[i]);
        }

        // 从机车管理器中清除机车
        std::vector<Loco*>::iterator iterloco = std::find(mLocos.begin(),mLocos.end(),decLocoArray[i]);
        if(iterloco != mLocos.end())
            mLocos.erase(iterloco);

        decString += wxString::Format("%s,",decLocoArray[i]->getName());

        // 最后删除机车
        delete decLocoArray[i];
        decLocoArray[i] = NULL;
    }

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,decString.ToUTF8().data());

    Track *pTrack = this->getTrackByName(decSectName);
    if(pTrack != NULL)
    {
        pTrack->setSectNode(pTrack->getSectNode());
    }
}

/// 删除所有机车
void LocoManager::deleteAllLocos(void)
{
    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    std::vector<Loco*>::iterator iter = mLocos.begin();
    for(;iter != mLocos.end();++iter)
    {
        if((*iter)->getSectNode() != NULL)
        {
            //std::lock_guard<std::mutex> lock(mTrackMutex);
            // 从轨道中清除这些机车
            std::map<wxString,Track>::iterator itertrack = mTracks.find((*iter)->getSectNode()->sectname);
            if(itertrack != mTracks.end())
                (*itertrack).second.delLoco((*iter));
        }

        delete (*iter);
        (*iter) = NULL;
    }

    mLocos.clear();
    mTracks.clear();
}

/// 得到指定名称的机车
Loco* LocoManager::getLocoByName(wxString locoName)
{
    if(locoName == "" || mLocos.empty())
        return NULL;

    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    std::vector<Loco*>::iterator iter = mLocos.begin();
    for(;iter != mLocos.end();++iter)
    {
        if((*iter)->getName() == locoName)
            return (*iter);
    }

    return NULL;
}

/// 工作区域改变
void LocoManager::changeWorkingRect(wxString sectName)
{
    //std::lock_guard<std::mutex> lock(mTrackMutex);

    std::map<wxString,tagSectNode*> allsects = WNodeManager::getSingleton().getAllSects();

    if(sectName == "")
    {
        std::map<wxString,tagSectNode*>::iterator itersect = allsects.begin();
        for(;itersect != allsects.end();++itersect)
        {
            //std::lock_guard<std::mutex> lock(mTrackMutex);
            mTracks[(*itersect).first].setSectNode((*itersect).second);
        }
    }
    else
    {
        std::map<wxString,tagSectNode*>::iterator itersect = allsects.find(sectName);
        if(itersect != allsects.end())
        {
            //std::lock_guard<std::mutex> lock(mTrackMutex);
            mTracks[(*itersect).first].setSectNode((*itersect).second);
        }
    }
}

/// 更新
void LocoManager::update(void)
{

}

/// 绘制
void LocoManager::draw(maindrawscene *painter)
{
    {
        //std::lock_guard<std::mutex> lock(mTrackMutex);
        // 绘制轨道
        std::map<wxString,Track>::iterator itertrack = mTracks.begin();
        for(;itertrack != mTracks.end();++itertrack)
            (*itertrack).second.draw(painter);
    }

    {
        //std::lock_guard<std::mutex> lock(m_LocoMutex);
        // 绘制机车
        std::vector<Loco*>::iterator iter = mLocos.begin();
        for(;iter != mLocos.end();++iter)
        {
            if((*iter) == NULL)
                continue;

            (*iter)->draw(painter);
        }

        iter = mLocos.begin();
        for(;iter != mLocos.end();++iter)
        {
            if((*iter) == NULL ||
                !(*iter)->m_mouseOvered)
                continue;

            std::vector<wxString> decNameArray;

            Loco *lastLoco = (*iter)->getLeftLoco();
            while(lastLoco != NULL)
            {
                decNameArray.push_back(lastLoco->getName());
                lastLoco = lastLoco->getLeftLoco();
            }

            std::reverse(decNameArray.begin(), decNameArray.end());

            decNameArray.push_back((*iter)->getName());

            Loco *nextLoco = (*iter)->getRightLoco();
            while(nextLoco != NULL)
            {
                decNameArray.push_back(nextLoco->getName());
                nextLoco = nextLoco->getRightLoco();
            }

            wxString decLocoNames = decNameArray[0];

            for(int i=1;i<decNameArray.size();i++)
            {
                decLocoNames += wxString::Format("-%s",decNameArray[i]);
            }

            painter->DrawText4(decLocoNames.ToUTF8().data(),
                               (*iter)->m_mousePosition,
                               wxColour(255,255,255,255),
                               0.0f,
                               0,
                               2.0f);
        }
    }
}

/// 得到当前选中轨道的名称
wxString LocoManager::getSelectedTrackName(void)
{
    //std::lock_guard<std::mutex> lock(mTrackMutex);
    std::map<wxString,Track>::iterator itertrack = mTracks.begin();
    for(;itertrack != mTracks.end();++itertrack)
    {
        SwitchState decstate = (*itertrack).second.isSelected();
        if(decstate != SwitchState::NOINIT)
            return wxString::Format("{\"sect\":\"%s\",\"state\":%d}",(*itertrack).first,(int)decstate);
    }

    return "";
}

/// 得到当前选中机车的ID
int LocoManager::getSelectedLocoId(void)
{
    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    for(int i=0;i<mLocos.size();i++)
    {
        if(mLocos[i]->isSelected())
            return i;
    }

    return -1;
}

/// 得到当前选中机车的名称
wxString LocoManager::getSelectedLocoName(void)
{
    //std::lock_guard<std::mutex> lock(m_LocoMutex);

    std::vector<Loco*>::iterator iter = mLocos.begin();
    for(;iter != mLocos.end();++iter)
    {
        if((*iter)->isSelected())
            return (*iter)->getName();
    }

    return "";
}

/// 处理鼠标事件
bool LocoManager::OnMMouseEvent(wxMouseEvent event)
{
    {
        //std::lock_guard<std::mutex> lock(mTrackMutex);
        // 处理轨道
        std::map<wxString,Track>::iterator itertrack = mTracks.begin();
        for(;itertrack != mTracks.end();++itertrack)
            (*itertrack).second.OnMMouseEvent(event);
    }

    {
        //std::lock_guard<std::mutex> lock(m_LocoMutex);
        // 处理机车
        std::vector<Loco*>::iterator iter = mLocos.begin();
        for(;iter != mLocos.end();++iter)
        {
            if((*iter) == NULL)
                continue;

            (*iter)->OnMMouseEvent(event);
        }
    }

    return false;
}
